﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Linq;
using DevExpress.Web.ASPxGridView;
using FlexySys.Common.Items;
using FlexySys.Common.Attributes;
using FlexySys.Web.Core;

namespace Web.Control.Item
{
    [CommonControl("Upload", "~/Control/Item/UserControl/FlexyUpload.ascx", "")]
    public partial class FlexyUpload : CommonControl, ICommonControl, ICommonCommandSubscriber
    {
        private bool isFilesSaved = false;

        public FlexyUpload()
        {

        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }

        private XElement GetFiles(bool syncFiles)
        {
            
            var files = new XElement("Files");
            GetChackedFiles()
                .ForEach(x =>
                {
                    files.Add(x);
                });

            SaveUploadFiles(syncFiles)
                .ForEach(x =>
            {
                files.Add(x);
            });

            DeleteUncheckedFiles(syncFiles);

            return files;
        }

        private List<XElement> GetChackedFiles()
        {
            List<XElement> files = new List<XElement>();
            if (this.dataItem != null && this.dataItem.Value !=null )
            {
                List<XElement> oldFiles = (((XElement)this.dataItem.Value)
                    .Elements("File"))
                    .ToList();

                List<object> iDs = dxGridView.GetSelectedFieldValues("ID");

                files = (from of in oldFiles
                         join ids in iDs on Guid.Parse(of.Attribute("ID").Value) equals Guid.Parse(ids.ToString())
                         select of).ToList();
            }
            return files;
        }

        private List<XElement> DeleteUncheckedFiles(bool delete)
        {
            List<XElement> deletedUncheckedFiles = new List<XElement>();

            if (this.dataItem != null && this.dataItem.Value !=null )
            {
                IEnumerable<XElement> oldFiles = (((XElement)this.dataItem.Value).Elements("File"));

                IEnumerable<object> iDs = dxGridView.GetSelectedFieldValues("ID");

                IEnumerable<XElement> files = (from of in oldFiles
                                               join ids in iDs on Guid.Parse(of.Attribute("ID").Value) equals Guid.Parse(ids.ToString())
                                               select of);

                deletedUncheckedFiles = oldFiles.Except(files).ToList();

                if (delete)
                {
                    deletedUncheckedFiles.ForEach(x =>
                    {
                        string file = Server.MapPath(string.Format("~/App_Data/Files/{0}/{1}", this.Page.DocumentType, x.Attribute("ID").Value));
                        File.Delete(file);
                    });
                }
            }

            return deletedUncheckedFiles;
        }

        private List<XElement> SaveUploadFiles(bool save)
        {
            List<XElement> files = new List<XElement>();

            if (dxUpload.UploadedFiles != null && dxUpload.HasFile && dxUpload.UploadedFiles.Length > 0)
            {
                XElement file = null;

                dxUpload.UploadedFiles
                    .ToList()
                    .ForEach(x =>
                    {
                        Guid id = Guid.NewGuid();
                        file = new XElement("File");
                        file.Add(new XAttribute("ID", id));
                        file.Add(new XAttribute("ContentLength", x.ContentLength));
                        file.Add(new XAttribute("ContentType", x.ContentType));
                        file.Add(new XAttribute("FileName", x.FileName));
                        try
                        {
                            if (save && !isFilesSaved)
                            {
                                
                                string path = Server.MapPath(string.Format("~/App_Data/Files/{0}", this.Page.DocumentType));
                                if (!Directory.Exists(path))
                                    Directory.CreateDirectory(path);

                                x.SaveAs( path +"\\" + id);
                            }
                            files.Add(file);
                        }
                        catch { }
                    });

                

            }

            isFilesSaved = save;
            return files;
        }

        private void LoadItems(IDataItem dataItem)
        {
            XElement files = null;

            if (this.dataItem != null || this.dataItem.Value!=null )
                files = (XElement)this.dataItem.Value;
            else
                files = XElement.Parse("<Files/>");

            if (files != null)
            {
                xmlDSFiles.Data = files.ToString(SaveOptions.DisableFormatting);
                xmlDSFiles.DataBind();
            }
        }

        private IDataItem dataItem = null;
        public IDataItem DataItem { 
            set {
                dataItem = value as IDataItem ;
                LoadItems(this.dataItem); 
            }
            get {
                dataItem.Value = GetFiles(true);
                return dataItem; 
            } 
        }

        protected void dxGridView_DataBound(object sender, EventArgs e)
        {
            if (this.Page.IsPostBack)
                return;

            ASPxGridView grid = sender as ASPxGridView;
            for (int i = 0; i < grid.VisibleRowCount; i++)
                    grid.Selection.SelectRow(i);
        }

        protected void dxGridView_CustomCallback(object sender, ASPxGridViewCustomCallbackEventArgs e)
        {
            if (!string.IsNullOrEmpty(e.Parameters) && this.Page.User.Identity.IsAuthenticated /*and check permission */)
            {
                ASPxGridView grid = sender as ASPxGridView;

                Guid Id = Guid.Parse(grid.GetRowValues(Convert.ToInt32(e.Parameters), "ID").ToString());

                XElement files = (XElement)this.dataItem.Value;

                var file = files
                    .Elements("File")
                    .First(x => Guid.Parse(x.Attribute("ID").Value) == Id);

                Session[Id.ToString()] = file;

            }

        }

        #region ICommonCommandSubscriber Members

        public void OnCommand(object sender, CommonCommandEventArgs args)
        {
            //args.Cancel = false;

            //var a = GetFiles(args.Cancel);
        }

        #endregion

    }
}